package uk.ac.shef.wit.simmetrics.tokenisers;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import uk.ac.shef.wit.simmetrics.wordhandlers.DummyStopTermHandler;
import uk.ac.shef.wit.simmetrics.wordhandlers.InterfaceTermHandler;

public class TokeniserIbatisId implements InterfaceTokeniser {
	private InterfaceTermHandler stopWordHandler = new DummyStopTermHandler();

	@Override
	public String getShortDescriptionString() {
		return "db id tokeniser";
	}

	@Override
	public String getDelimiters() {
		return "_";
	}

	@Override
	public InterfaceTermHandler getStopWordHandler() {
		return stopWordHandler;
	}

	@Override
	public void setStopWordHandler(InterfaceTermHandler stopWordHandler) {
		this.stopWordHandler = stopWordHandler;
	}
	public static final int START = 0;
	//lex word, such a_b, a__b aB
	public static final int IN_BREAK = 1 ; // '__' ' ', '$';
	public static final int IN_UPPER= 2; // 'A', 'B'
	public static final int IN_LOWER=3; // 'a','b','c';
	public static final int IN_OTHER = 4; // number , etc..
	public static final int END= 100;
	/**
	 * start->
	 */
	@Override
	public ArrayList<String> tokenizeToArrayList(String input) {
		final ArrayList<String> returnVect = new ArrayList<String>();
        int curPos = 0;
        StringBuffer sb = new StringBuffer();
        int fms = START;
        while (curPos < input.length()) {
        	char c = input.charAt(curPos);
        	if (c == '_' || c == ' ' || c == '$'){ //if they are in the head of a string, omit them 
        		switch (fms){        		
        		case START:
        		case IN_BREAK:
        			break; //directly omit it
        		case IN_UPPER:
        		case IN_LOWER:
        		case IN_OTHER:
        			fms = IN_BREAK;
        			returnVect.add(sb.toString());
        			sb.setLength(0);
        			break;
        		}
        	}else{
        		if (Character.isUpperCase(c)){
        			if (fms == IN_LOWER || fms == IN_OTHER){
        				returnVect.add(sb.toString());
        				sb.setLength(0);
        			}
        			fms = IN_UPPER;
        			sb.append(Character.toLowerCase(c));
        			
        		}else if (Character.isLowerCase(c)){
        			if (fms == IN_OTHER){
        				returnVect.add(sb.toString());
        				sb.setLength(0);
        			}else if (fms == IN_UPPER){
        				if (sb.length() > 1){
        					returnVect.add(sb.toString());
            				sb.setLength(0);
        				}
        			}
        			fms = IN_LOWER;
        			sb.append(c);
        		}else{
        			if (fms != START){
        				fms = IN_OTHER;
        				sb.append(c);
        			}
        		}
        	}
        	curPos++;
        	if (curPos == input.length()){
        		returnVect.add(sb.toString());
				sb.setLength(0);
				fms = END;
        	}
        }
        return returnVect;
	}

	@Override
	public Set<String> tokenizeToSet(String input) {
		final Set<String> returnSet = new HashSet<String>();
		returnSet.addAll(tokenizeToArrayList(input));
		return returnSet;
	}

}
